/**
 *	@file	safaril_act.c
 *	@brief	サファリレイアウト　アクター制御
 *	@author	Miyuki Iwasawa
 */

#include "common.h"
#include "system/procsys.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/brightness.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/window.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/fontproc.h"
#include "system/snd_tool.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/wipe.h"
#include "system/wordset.h"
#include "system/buflen.h"
#include "gflib/msg_print.h"
#include "gflib/strbuf_family.h"
#include "application/app_tool.h"
#include "savedata/config.h"

#include "application/safari_l.h"

#include "safaril_sys.h"
#include "safaril_sub.h"
#include "safaril_act.h"
#include "safaril_gra.naix"
#include "data/clact_util/clact_header.naix"

/////////////////////////////////////////////////////////////////////////////
/**
 *	定義エリア
 */
/////////////////////////////////////////////////////////////////////////////

#define SAFARIL_ACTRES_MAX	(16)
#define SAFARIL_ACTMAX	(128)

///パネルOAMリソースの数
#define OAM_CHR_RES_MAX	(12)
#define OAM_PAL_RES_MAX	(1)
#define OAM_CEL_RES_MAX	(1)
#define OAM_ANM_RES_MAX	(1)

///リソースタイプの定義
enum{
 RESTYPE_CHR,
 RESTYPE_PAL,
 RESTYPE_CEL,
 RESTYPE_ANM,
};

///パネルリソース名定義
#define RES_CHRID	(NARC_safaril_gra_panel01_ncgr)
#define RES_CELID	(NARC_safaril_gra_oam_panel_ncer)
#define RES_ANMID	(NARC_safaril_gra_oam_panel_nanr)
#define RES_PALID	(NARC_safaril_gra_oam_panel_nclr)
#define RES_NOCOMP	(0)
#define RES_NOTRANS	(0)
#define RES_HEADID (0xe000)

static const TCATS_OAM_INIT safaril_coi = {
	0,128,		///< メイン	OAM管理領域・開始/終了
	0,32,		///< メイン	アフィン管理領域・開始/終了
	0,128,		///< サブ	OAM管理領域・開始/終了
	0,32,		///< サブ	アフィン管理領域・開始/終了
};
static const TCATS_CHAR_MANAGER_MAKE safaril_ccmm = {
	SAFARIL_ACTRES_MAX,	//ID制御数
//	64*1024,	//メイン画面サイズ(byte単位) 64kbyte
//	16*1024,	//サブ画面サイズ(byte単位) 16kbyte
	0,0,
	GX_OBJVRAMMODE_CHAR_1D_64K,	//メインOBJモード指定
	GX_OBJVRAMMODE_CHAR_1D_64K,	//サブOBJモード指定
};
//TCATS_RES_ARC
static const TCATS_RESOURCE_FILE_LIST safaril_actres_list = {
	NARC_clact_header_safaril_chr_resdat,		// キャラクタ
	NARC_clact_header_safaril_pal_resdat,		// パレット
	NARC_clact_header_safaril_cell_resdat,		// セル
	NARC_clact_header_safaril_canm_resdat,		// セルアニメ
	TCATS_RESID_NULL,							// マルチセル
	TCATS_RESID_NULL,							// マルチセルアニメ
	NARC_clact_header_safaril_celact_cldat		// ヘッダー
};


/////////////////////////////////////////////////////////////////////////////
/**
 *	プロトタイプエリア
 */
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
/**
 *	プログラムエリア
 */
/////////////////////////////////////////////////////////////////////////////
static void panel_ResManagerInit(SAFARIL_PANEL_MAN* wk);
static void panel_ResManagerRelease(SAFARIL_PANEL_MAN* wk);
static void panel_LoadResArc(SAFARIL_PANEL_MAN* wk);
static void SafariLPanel_SetRefarenceCSP(SAFARIL_PANEL_MAN* wk,CLACT_SET_PTR csp);

/**
 *	@brief	サファリ　アクターシステム初期化
 */
void SafariL_ActorSysInit(SAFARIL_WORK* wk)
{
	initVramTransferManagerHeap(32,wk->heapID);

	//セルアクターシステム初期化
	wk->pActSys = CATS_AllocMemory(wk->heapID);

	CATS_SystemInit( wk->pActSys,
		&safaril_coi,&safaril_ccmm,4 );

	//OAM初期化
	REND_OAM_UtilOamRamClear_Main(wk->heapID);
	REND_OAM_UtilOamRamClear_Sub(wk->heapID);
}

/*
 *	@brief	サファリ　アクターシステム開放
 */
void SafariL_ActorSysRelease(SAFARIL_WORK *wk)
{
	CATS_FreeMemory(wk->pActSys);
	wk->pActSys = NULL;
	DellVramTransferManager();

	//OAM初期化
	REND_OAM_UtilOamRamClear_Main(wk->heapID);
	REND_OAM_UtilOamRamClear_Sub(wk->heapID);
}

/*
 *	@brief	サファリ　アクターリソースセット初期化
 */
void SafariL_ActorResInit(SAFARIL_WORK *wk)
{
	if(wk->pActSys == NULL){
		return;
	}

	//セルアクターシステム初期化
	wk->pActRes = CATS_ResourceCreate(wk->pActSys);
	CATS_ClactSetInit( wk->pActSys, wk->pActRes,SAFARIL_ACTMAX+PANEL_VIEW_MAX*2);

	CATS_ResourceLoadBinaryEx( wk->pActSys, wk->pActRes,
		&safaril_actres_list,CATS_CGXOFS_OFFSET,CATS_PLTTOFS_AREA);

	SafariLPanel_SetRefarenceCSP(wk->panel,CATS_GetClactSetPtr(wk->pActRes));
}

/*
 *	@brief	サファリ　アクターリソースセット開放
 */
void SafariL_ActorResRelease(SAFARIL_WORK *wk)
{
	if(wk->pActRes == NULL){
		return;
	}
	CATS_ResourceDestructor(wk->pActSys,wk->pActRes);
	wk->pActRes = NULL;
}

/*
 *	@brief	サファリ　アクター描画メイン
 */
void SafariL_ActorMain(SAFARIL_WORK *wk)
{
	if(wk->panel != NULL){
		SafariLPanel_Draw(wk->panel);
	}
	if(wk->pActRes != NULL){
		CATS_Draw(wk->pActRes);
	}
	return;
}

/*
 *	@brief	サファリ　アクター転送メイン
 */
void SafariL_ActorTrans(SAFARIL_WORK* wk)
{
	if(wk->pActSys == NULL){
		return;
	}
	CATS_RenderOamTrans();
}

/**
 *	@brief	サファリ　パネルOAM リソースマネージャ初期化
 *
 *	@param	heapID	ヒープID
 *	@param	actmax	確保するセルアクター領域の個数
 *	@param	vramType	描画画面指定(PORUOAM_DRAW_MAIN/SUB/BOTH)
 *	@param	cgx_transofs	キャラクタ転送オフセット指定
 */
SAFARIL_PANEL_MAN* SafariLPanel_Init(int heapID,u16 actmax,
		u16 vramType,CATS_CGXOFS_MODE cgx_transofs)
{
	SAFARIL_PANEL_MAN* wk;

	wk = sys_AllocMemory(heapID,sizeof(SAFARIL_PANEL_MAN));
	MI_CpuClear8(wk,sizeof(SAFARIL_PANEL_MAN));

	//パラメータ保存
	wk->heapID = heapID;
	wk->pal_num = SAFARIL_POAM_PALNUM;
	wk->act_max = actmax;
	wk->vramType = vramType;
	wk->cgx_transofs = cgx_transofs;

	panel_ResManagerInit(wk);
	return wk;
}

/**
 *	@brief	サファリ　パネルOAM　マネージャ解放
 */
void SafariLPanel_Release(SAFARIL_PANEL_MAN* wk)
{
	panel_ResManagerRelease(wk);
	MI_CpuClear8(wk,sizeof(SAFARIL_PANEL_MAN));
	sys_FreeMemoryEz(wk);
	wk = NULL;
}

/*
 *	@brief	サファリ　パネルOAM　リソース読み替え
 */
void SafariLPanel_ResChange(SAFARIL_PANEL_MAN* wk,u8 idx,u8 panelID)
{
	CLACT_U_RES_OBJ_PTR	obj;

	//キャラクタリソース読み替え
	obj = wk->resObjTbl[RESTYPE_CHR]->tbl[idx];
	CLACT_U_ResManagerResChgArcChar(
		wk->resMan[RESTYPE_CHR], obj,
		ARC_SAFARIL_GRA,RES_CHRID+panelID,RES_NOCOMP,wk->heapID);

	CLACT_U_CharManagerReTrans(obj);
}

/**
 *	@brief　サファリ　パネルOAM　描画
 */
void SafariLPanel_Draw(SAFARIL_PANEL_MAN* wk)
{
	if(wk->cas == NULL){
		return;
	}
	CLACT_Draw(wk->cas);
}

static void SafariLPanel_SetRefarenceCSP(SAFARIL_PANEL_MAN* wk,CLACT_SET_PTR csp)
{
	wk->ref_csp = csp;
}

/**
 *	@brief	サファリ　パネルOAM　作成
 */
CATS_ACT_PTR SafariLPanel_ObjAdd(SAFARIL_PANEL_MAN* wk,
	u16 x,u16 y,u8 bg_pri,u8 spri,u8 idx,u8 panelID, int vram_type)
{
	u32	palid;
	CATS_ACT_PTR cap = NULL;
	CLACT_ADD	 add;
	CLACT_U_RES_OBJ_PTR	obj;

	//ワークメモリ確保
	cap = sys_AllocMemory(wk->heapID, sizeof(TCATS_ACT) );
	MI_CpuClear8(cap,sizeof(TCATS_ACT));

	//ヘッダーメモリ確保
	cap->act_htp = sys_AllocMemory(wk->heapID,sizeof(CLACT_HEADER_TBL));
	cap->act_htp->tbl = sys_AllocMemory(wk->heapID,sizeof(CLACT_HEADER));
	cap->act_hd = cap->act_htp->tbl;

	//ヘッダー生成
	CLACT_U_MakeHeader(
		cap->act_hd,
		RES_HEADID+idx,RES_HEADID,
		RES_HEADID,RES_HEADID,
		CLACT_U_HEADER_DATA_NONE,CLACT_U_HEADER_DATA_NONE,
		RES_NOTRANS, bg_pri,
		wk->resMan[RESTYPE_CHR],wk->resMan[RESTYPE_PAL],
		wk->resMan[RESTYPE_CEL],wk->resMan[RESTYPE_ANM],
		NULL,NULL);

	// OAM登録
	if(wk->ref_csp != NULL){
		add.ClActSet	= wk->ref_csp;
	}else{
		add.ClActSet	= wk->cas;
	}
	add.ClActHeader = cap->act_hd;

	add.mat.x		= FX32_CONST(x);
	add.mat.y		= FX32_CONST(y);
	add.mat.z		= FX32_CONST(0);

	if(vram_type == NNS_G2D_VRAM_TYPE_2DSUB){
		add.mat.y += SUB_SURFACE_Y;
	}

	add.sca.x		= FX32_ONE;			// 拡縮率
	add.sca.y		= FX32_ONE;
	add.sca.z		= FX32_ONE;

	add.rot			= 0;				// 回転角
	add.pri			= spri;				// 優先度
	add.DrawArea	= vram_type;		// 描画面
	add.heap		= wk->heapID;		// ヒープID

	//リソース読み替え
	SafariLPanel_ResChange(wk,idx,panelID);

	cap->act = CLACT_Add(&add);			//登録処理

	if(cap->act == NULL){
		GF_ASSERT(0 &&"safari panel oam add failed");
	}
	return cap;
}

/**
 *	@brief	サファリ　パネルOAM　削除
 */
void SafariLPanel_ObjDelete(CATS_ACT_PTR oam)
{
	//アクター削除
	CATS_ActorPointerDelete_S(oam);
}


/**
 *	@brief	サファリ　パネルOAMリソースマネージャ作成
 */
static void panel_ResManagerInit(SAFARIL_PANEL_MAN* wk)
{
	u32 i, j;
	u8	resnum[] = {OAM_CHR_RES_MAX,OAM_PAL_RES_MAX,
					OAM_CEL_RES_MAX,OAM_ANM_RES_MAX};

	wk->cas  = CLACT_U_SetEasyInit(wk->act_max, &wk->renddata,wk->heapID);

	// リソースマネージャー作成&テーブル初期化
	for( i=0; i< SAFARIL_PANEL_RESMAX; i++ ){
		wk->resMan[i] = CLACT_U_ResManagerInit(resnum[i],i, wk->heapID );
		wk->resObjTbl[i] = CLACT_U_ResManagerResObjTblMake(resnum[i],wk->heapID);
		for( j=0; j<wk->resObjTbl[i]->tbl_num; j++ ){
			wk->resObjTbl[i]->tbl[j] = NULL;
		}
	}

	//リソースロード
	panel_LoadResArc(wk);
}

/**
 *	@brief	サファリ　システムOAMリソースマネージャ解放
 */
static void panel_ResManagerRelease(SAFARIL_PANEL_MAN* wk)
{
	u32	i;

	CLACT_DestSet( wk->cas );	// セット破棄
	CLACT_U_CharManagerDeletes( wk->resObjTbl[RESTYPE_CHR] );	// キャラデータ破棄
	CLACT_U_PlttManagerDeletes( wk->resObjTbl[RESTYPE_PAL] );	// パレットデータ破棄

	for( i=0; i<SAFARIL_PANEL_RESMAX; i++ ){
		// リソースオブジェテーブル破棄
		CLACT_U_ResManagerResObjTblDelete( wk->resObjTbl[i] );
		// リソースマネージャ破棄
		CLACT_U_ResManagerDelete( wk->resMan[i] );
	}
}

/**
 *	@brief	サファリ　システムOAMリソース初期設定
 */
static void panel_LoadResArc(SAFARIL_PANEL_MAN* wk)
{
	int i;
	CLACT_U_RES_MANAGER_PTR	res;
	CLACT_U_RES_OBJ_TBL* obj;
	CLACT_U_RES_OBJ_PTR tmp;

	//キャラクタリソース取得
	obj = wk->resObjTbl[RESTYPE_CHR];
	for(i = 0;i < OAM_CHR_RES_MAX;i++){
		obj->tbl[i] = CLACT_U_ResManagerResAddArcChar(wk->resMan[RESTYPE_CHR],
			ARC_SAFARIL_GRA,RES_CHRID+i,RES_NOCOMP,RES_HEADID+i,wk->vramType,wk->heapID);

		GF_ASSERT((obj->tbl[i]!=NULL)&&"safari char resload failed");

		switch(wk->cgx_transofs){
		case CATS_CGXOFS_AREA:
			CLACT_U_CharManagerSetAreaCont(obj->tbl[i]);
			break;
		case CATS_CGXOFS_ADJUST:
			CLACT_U_CharManagerSetCharModeAdjustAreaCont(obj->tbl[i]);
			break;
		case CATS_CGXOFS_OFFSET:
		default:
			CLACT_U_CharManagerSetCharModeAdjust(obj->tbl[i]);
//			CLACT_U_CharManagerSet(obj->tbl[i]);
			break;
		}
	}

	//セル&セルアニメリソース取得
	for(i = 0;i < 2;i++){
		obj = wk->resObjTbl[RESTYPE_CEL+i];
		obj->tbl[0] = CLACT_U_ResManagerResAddArcKindCell(wk->resMan[RESTYPE_CEL+i],
			ARC_SAFARIL_GRA,RES_CELID+i,RES_NOCOMP,RES_HEADID,RESTYPE_CEL+i,wk->heapID);

		GF_ASSERT((obj->tbl[0]!=NULL)&&"safari cell&canm resload failed");
	}

	//初期パレットリソース取得
	obj = wk->resObjTbl[RESTYPE_PAL];
	obj->tbl[0] = CLACT_U_ResManagerResAddArcPltt(wk->resMan[RESTYPE_PAL],
		ARC_SAFARIL_GRA,RES_PALID,RES_NOCOMP,RES_HEADID,
		wk->vramType,SAFARIL_POAM_PALNUM,wk->heapID);

	GF_ASSERT((obj->tbl[0]!=NULL)&&"safari panel oam pal resload failed");
	CLACT_U_PlttManagerSetCleanArea(obj->tbl[0]);
//	CLACT_U_PlttManagerSet(obj->tbl[0]);
}

